home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_100 / 194_01 / archive.c < prev    next >
Text File  |  1985-11-13  |  8KB  |  413 lines

  1. /* [ARCHIVE.C of JUGPDS Vol.17]
  2. *****************************************************************
  3. *                                *
  4. *       Written by  Hakuo Katayose (JUG-CP/M No.179)        *
  5. *            49-114 Kawauchi-Sanjuunin-machi        *
  6. *            Sendai, Miyagi 980                          *
  7. *            Phone: 0222-61-3219                *
  8. *                                *
  9. *       Edited & tested by Y. Monma (JUG-C/M Disk Editor)       * 
  10. *                                *
  11. *****************************************************************
  12. */
  13. /* archive - file maintaner */
  14.  
  15. #include    "stdio.h"
  16.  
  17. #define    UPD    'u'
  18. #define    TBL    't'
  19. #define    EXTR    'x'
  20. #define    PRINT    'p'
  21. #define    DEL    'd'
  22.  
  23. #define    MAXFILES    8
  24. #define    NAMESIZE    16
  25. #define    MAXCHARS    32000
  26.  
  27. #define    makhdr(name, head)    sprintf(head,"-h- %s %d\n", name, fsize(name))
  28.  
  29. main(argc, argv)
  30. int    argc;
  31. char *argv[];
  32.  
  33. {
  34.     char    aname[NAMESIZE], cmd;
  35.  
  36.     if (argc < 3) {
  37.         error("Usage: archive {dptux} archname [files]");
  38.         exit();
  39.         }
  40.     strcpy(aname, argv[2]);
  41.     getfns(argc, argv);
  42.     if ((cmd = tolower(argv[1][0])) == UPD)
  43.         update(aname);
  44.     else if (cmd == TBL)
  45.         table(aname);
  46.     else if (cmd == PRINT || cmd == EXTR)
  47.         extrac(aname, cmd);
  48.     else if (cmd == DEL)
  49.         delete(aname);
  50.     else
  51.         error("Usage: archive {dptux} archname [files]");
  52. }
  53.  
  54. /* getfns -get file names, check for duplicates */
  55. char    fname[MAXFILES][NAMESIZE];
  56. int    fstat[MAXFILES], nfiles, errcnt;
  57.  
  58. getfns(argc, argv)
  59. char *argv[];
  60.  
  61. {
  62.     int    i, j;
  63.  
  64.     errcnt = 0;
  65.     nfiles = argc - 3;
  66.     if (nfiles > MAXFILES)
  67.         error("Too many file names!");
  68.     for (i = 0; i < nfiles; i++) {
  69.         strcpy(fname[i], argv[i+3]);
  70.         fstat[i] = NO;
  71.     }
  72.     for (i = 0; i < nfiles - 1; i++)
  73.         for (j = i + 1; j < nfiles; j++)
  74.             if (!strcmp(fname[i], fname[j]))
  75.                 fprintf(STDERR,"%s: duplicate file name.",
  76.                         fname[i]);
  77. }
  78.  
  79. /* update - update existing files, add new ones at end */
  80. update(aname)
  81. char    *aname;
  82.  
  83. {
  84.     FILE    afd, tfd;
  85.     char    *tname;
  86.     int    i;
  87.  
  88.     tname = "archtemp";
  89.     if (fopen(aname, &afd) == ERROR) {
  90.         if (fcreat(aname, &afd) == ERROR)
  91.             cant(aname);
  92.         }
  93.     if (fcreat(tname, &tfd) == ERROR)
  94.         cant(tname);
  95.     replac(&afd, &tfd, UPD, &errcnt);
  96.     for (i = 0; i < nfiles; i++)
  97.         if (fstat[i] == NO) {
  98.             addfil(fname[i], &tfd, &errcnt);
  99.             fstat[i] = YES;
  100.         }
  101.     fclose(&afd);
  102.     putc(CPMEOF, &tfd);
  103.     fclose(&tfd);
  104.     if (!errcnt)
  105.         amove(tname, aname);
  106.     else
  107.         remark("Fatal errors - archive not altered.");
  108.     unlink(tname);
  109. }
  110.  
  111. /* replac - replace or delete files */
  112. replac(afd, tfd, cmd, errcnt)
  113. FILE    *afd, *tfd;
  114. int    *errcnt;
  115.  
  116. {
  117.     char    in[MAXLINE], uname[NAMESIZE];
  118.     int    size;
  119.  
  120.     while (gethdr(afd, in, uname, &size) != EOF)
  121.         if (filarg(uname) == YES) {
  122.             if (cmd == UPD)    
  123.                 addfil(uname, tfd, errcnt);
  124.             fskip(afd, size);
  125.         } else {
  126.             fputs(in, tfd);
  127.             acopy(afd, tfd, size);
  128.         }
  129. }
  130.  
  131. /* gethdr - get header info from fd */
  132. gethdr(fd, buf, name, size)
  133. FILE    *fd;
  134. char    buf[MAXLINE], name[NAMESIZE];
  135. int    *size;
  136.  
  137. {
  138.     int    len, i;
  139.     char    temp[NAMESIZE];
  140.  
  141.     if (getlin(buf, fd) == NULL)
  142.         return (EOF);
  143.     i = 0;
  144.     len = getwrd(buf, &i, temp);
  145.     if (strcmp(temp, "-h-"))
  146.         error("archive not in proper format.");
  147.     len = getwrd(buf, &i, name);
  148.     *size = atoi(buf+i);
  149.     return YES;
  150. }
  151.  
  152. /* fskip - skip n characters on file fd */
  153. fskip(fd, n)
  154. FILE    *fd;
  155.  
  156. {
  157.     int    c;
  158.  
  159.     while (n--)
  160.         if ((c = getc(fd)) == EOF || c == CPMEOF)
  161.             break;
  162. }
  163.  
  164. /* filarg - check if namematches argument list */
  165. filarg(name)
  166. char    *name;
  167.  
  168. {
  169.     int    i;
  170.  
  171.     if (nfiles <= 0)
  172.           return (YES);
  173.     for (i = 0; i < nfiles; i++) {
  174.         if (!strcmp(name, fname[i])) {
  175.             fstat[i] = YES;
  176.             return (YES);
  177.              }
  178.     }
  179.     return (NO);
  180. }
  181.  
  182. /* acopy - copy size characters from fdi to fdo */ 
  183. acopy(fdi, fdo, size)
  184. FILE    *fdi, *fdo;
  185.  
  186. {
  187.     int    c;
  188.  
  189.     while (size--) {
  190.         if ((c = getc(fdi)) == EOF || c == CPMEOF)
  191.                     break;
  192.         putc(c, fdo);
  193.         }
  194. }
  195.  
  196. /* addfil - add file "name" to archive */
  197. addfil(name, fd, errcnt)
  198. char    *name;
  199. FILE    *fd;
  200. int    *errcnt;
  201.  
  202. {
  203.     char    head[MAXLINE];
  204.     FILE    nfd;
  205.  
  206.     if (fopen(name, &nfd) == ERROR) {
  207.         fprintf(STDERR, "%s:  can't add.", name);
  208.         (*errcnt)++;
  209.     }
  210.     if (!*errcnt) {
  211.         makhdr(name, head);
  212.         fputs(head, fd);
  213.         fcopy(&nfd, fd);
  214.         fclose(&nfd);
  215.     }
  216. }
  217.  
  218. /* amove - move file1 to file2 */
  219. amove(file1, file2)
  220. char *file1, *file2;
  221.  
  222. {
  223.     FILE    fp1, fp2;
  224.  
  225.     if (fopen(file1, &fp1) == ERROR)
  226.         cant(file1);
  227.     else if (fcreat(file2, &fp2) == ERROR)
  228.         cant(file2);
  229.  
  230.     fcopy(&fp1, &fp2);
  231.  
  232.     fclose(&fp1);
  233.     putc(CPMEOF,&fp2);
  234.     fclose(&fp2);
  235. }
  236.  
  237. /* fcpy - copy file fp1 to fle fp2 */
  238. fcopy(fp1, fp2)
  239. FILE *fp1, *fp2;
  240.  
  241. {
  242.     int c;
  243.  
  244.     while ((c = getc(fp1)) != EOF && c != CPMEOF)
  245.         putc(c,fp2);
  246. }
  247.  
  248. /* cant - can't open file, exit to CP/M */
  249. cant(fname)
  250. char *fname;
  251.  
  252. {
  253.     fprintf(STDERR, " can't open %s\n", fname);
  254.     exit(1);
  255. }
  256.  
  257. /* fsize - size of file in characters */
  258. fsize(name)
  259. char    *name;
  260.  
  261. {
  262.     int    size;
  263.     FILE    fp;
  264.     int    c;
  265.  
  266.     if (fopen(name, &fp) == ERROR)
  267.         return ERROR;
  268.     else {
  269.         for (size = 0; (c = getc(&fp)) != EOF && c != CPMEOF; size++)
  270.             ;
  271.         fclose(&fp);
  272.         return size;
  273.     }
  274. }
  275.  
  276. /* getwrd - get non-blank word from in[i] into out, increment i */
  277. getwrd(in, i, out)
  278. char in[], out[];
  279. int  *i;
  280.  
  281. {
  282.     int    j;
  283.  
  284.     while (in[(*i)] == ' ' || in[(*i)] == '\t')
  285.             (*i)++;
  286.     j = 0;
  287.     while (    in[(*i)] != '\0' && in[(*i)] != ' ' &&
  288.         in[(*i)] != '\t' && in[(*i)] != NEWLINE)
  289.         out[j++] = in[(*i)++];
  290.     out[j] = '\0';
  291.     return j;
  292. }
  293.  
  294. /* getlin - get next line from fp */
  295. getlin(s, fp)
  296. FILE    *fp;
  297. char    *s;
  298.  
  299. {
  300.     char    *p;
  301.     int    c;
  302.  
  303.     p = s;
  304.     while((c = getc(fp)) != EOF && c != CPMEOF && c != NEWLINE)
  305.         *s++ = c;
  306.     if(c == NEWLINE)
  307.         *s++ = c;
  308.     *s = '\0';
  309.     return(s-p);
  310. }
  311.  
  312. /* table - print table of archive contents */
  313. #define    tprint(buf)    (fputs(buf, STDOUT))
  314.  
  315. table(aname)
  316. char    *aname;
  317.  
  318. {
  319.     FILE    afd;
  320.     char    in[MAXLINE], lname[NAMESIZE];
  321.     int    size;
  322.  
  323.     if (fopen(aname, &afd) == ERROR)
  324.         cant(aname);
  325.     while (gethdr(&afd, in, lname, &size) != EOF) {
  326.         if (filarg(lname) == YES)
  327.             tprint(in);
  328.         fskip(&afd, size);
  329.     }
  330.     notfnd();
  331.     fclose(&afd);
  332. }
  333.  
  334. /* extract - extract files from archive */ 
  335. extrac(aname, cmd)
  336. char    *aname;
  337.  
  338. {
  339.     FILE    afd, efd;
  340.     char    in[MAXLINE], ename[NAMESIZE];
  341.     int    size, fd;
  342.  
  343.     if (fopen(aname, &afd) == ERROR)
  344.         cant(aname);
  345.     if (cmd == PRINT)
  346.         fd = STDOUT;
  347.     else
  348.         fd =  ERROR;
  349.     while (gethdr(&afd, in, ename, &size) != EOF)
  350.         if (filarg(ename) == NO)
  351.             fskip(&afd, size);
  352.         else {
  353.             if (fd != STDOUT)
  354.                 fd = fcreat(ename, &efd);
  355.             if (fd == ERROR) {
  356.                 fprintf(STDERR,"%s:  can't create.", ename);
  357.                 errcnt++;
  358.                 fskip(&afd, size);
  359.                 }
  360.             else {
  361.                 if (fd == STDOUT)
  362.                     acopy(&afd, STDOUT, size);
  363.                 else
  364.                     acopy(&afd, &efd, size);
  365.                 if (fd != STDOUT)
  366.                     fclose(&efd);
  367.                 }
  368.             }
  369.     notfnd();
  370. }
  371.  
  372. /* delete - delete files from archive */
  373. delete(aname)
  374. char    *aname;
  375.  
  376. {
  377.     FILE    afd, tfd;
  378.     char    *tname;
  379.  
  380.  
  381.     tname = "archtemp";
  382.  
  383.     if (nfiles <= 0)
  384.         error("delete by name only.");
  385.     if (fopen(aname, &afd) == ERROR)
  386.         cant(aname);
  387.     if (fcreat(tname, &tfd) == ERROR)
  388.         cant(tname);
  389.     replac(&afd, &tfd, DEL, &errcnt);
  390.     notfnd();
  391.     fclose(&afd);
  392.     putc(CPMEOF, &tfd);
  393.     fclose(&tfd);
  394.     if (errcnt == 0)
  395.         amove(tname, aname);
  396.     else
  397.         remark("Fatal errors - archive not altered.");
  398.     unlink(tname);
  399. }
  400.  
  401. /* notfnd - not found */ 
  402. notfnd()
  403.  
  404. {
  405.     int    i;
  406.  
  407.     for (i = 0; i < nfiles; i++)
  408.         if (fstat[i] == NO) {
  409.             fprintf(STDERR,"%s:  not in archive.", fname[i]);
  410.             errcnt++;
  411.             }
  412. }
  413.